package com.snail.controller;

import com.snail.constants.SystemConstants;
import com.snail.exception.BizException;
import com.snail.model.vo.user.LoginUser;
import com.snail.result.Result;
import com.snail.result.ResultCode;
import com.snail.service.BizBigFileService;

import com.snail.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @author Monica
 * @description
 * @date 2025/8/22 10:00
 */
@Slf4j
@RestController
@RequestMapping("/bigFile")
public class BizBigFileController {


    @Autowired
    private BizBigFileService bigFileService;


    @RequestMapping("/checkChunk")
    public Result<List<Integer>> checkChunk(String fileMd5, List<Integer> chunkNums) {
        LoginUser currentUser = SecurityUtils.getCurrentUser();
        Long userId = currentUser.getUserId();
        return bigFileService.checkChunk(fileMd5, chunkNums, userId);
    }

    @RequestMapping("/uploadChunk")
    public Result uploadChunk(String fileMd5, List<Integer> chunkNums, List<MultipartFile> files) {
        // 1. 基础参数校验
        if (chunkNums == null || files == null || chunkNums.size() != files.size()) {
            throw new BizException(ResultCode.PARAM_IS_NULL, "分块号与文件数量不匹配");
        }
        if (chunkNums.isEmpty()) {
            throw new BizException(ResultCode.PARAM_IS_NULL, "分块号列表不能为空");
        }

        List<String> tempFilePaths = new ArrayList<>();
        File parentDir = null;

        try {
            // 2. 创建统一的临时目录（确保父目录存在）
            parentDir = new File(Paths.get(SystemConstants.TEMP_DIR).toAbsolutePath() + "/minio_" + fileMd5);
            if (!parentDir.exists() && !parentDir.mkdirs()) {
                throw new BizException(ResultCode.SYSTEM_RESOURCE_ERROR, "创建临时目录失败: " + parentDir.getAbsolutePath());
            }

            // 3. 循环处理每个分块
            for (int i = 0; i < chunkNums.size(); i++) {
                Integer chunkNum = chunkNums.get(i);
                MultipartFile file = files.get(i);

                // 3.1 分块号校验
                if (chunkNum == null || chunkNum < 0) {
                    throw new BizException(ResultCode.PARAM_IS_NULL, "无效的分块号: " + chunkNum);
                }
                // 3.2 文件校验（非空）
                if (file.isEmpty()) {
                    throw new BizException(ResultCode.PARAM_IS_NULL, "分块文件为空，分块号: " + chunkNum);
                }

                // 3.3 保存临时文件
                File tempFile = new File(parentDir, chunkNum + ".merge");
                file.transferTo(tempFile);
                tempFilePaths.add(tempFile.getAbsolutePath());

                boolean success = bigFileService.uploadChunk(fileMd5, chunkNums, tempFilePaths);
            }

            // 4. 返回成功上传的分块号
            return Result.success();

        } catch (IOException e) {
            throw new BizException(ResultCode.USER_UPLOAD_FILE_ERROR, "文件写入失败: " + e.getMessage());
        } catch (BizException e) {
            // 保留业务异常信息
            throw e;
        } catch (Exception e) {
            throw new BizException(ResultCode.USER_UPLOAD_FILE_ERROR, "分块处理异常: " + e.getMessage());
        } finally {
            // 5. 清理临时文件（无论成功失败都删除）
            for (String path : tempFilePaths) {
                File file = new File(path);
                if (file.exists() && !file.delete()) {
                    log.warn("临时文件删除失败: " + path);
                }
            }
            // 可选：如果所有分块处理完成，删除空目录
            if (parentDir != null && parentDir.exists() && parentDir.listFiles() != null && Objects.requireNonNull(parentDir.listFiles()).length == 0) {
                parentDir.delete();
            }
        }
    }
}
